#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QFileDialog>
#include <QMessageBox>
#include <QMouseEvent>
#include <QDebug>
#include <QDesktopWidget>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    initInterface();
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::initInterface()
{
    ui->pushButton_start->setEnabled(false);
    ui->pushButton_stop->setEnabled(false);
    ui->pushButton_replay->setEnabled(false);
    ui->horizontalSlider_timeline->setEnabled(false);
    ui->progressBar_save_time->setVisible(false);
    ui->label_save_message->setVisible(false);
}

void MainWindow::initVideo(QString video_path)
{
    if(video_path != "")
    {
        ui->horizontalSlider_timeline->setEnabled(true);
        ui->pushButton_start->setEnabled(true);
        ui->pushButton_stop->setEnabled(true);
        path_open = video_path.toStdString();
        capture.open(path_open);
        capture >> frame;
        total_frame_number = capture.get(CV_CAP_PROP_FRAME_COUNT);
        rate = capture.get(CV_CAP_PROP_FPS);
        speed = 1000/rate;
        QImage img = QImage((const unsigned char*)(frame.data),
                            frame.cols,
                            frame.rows,
                            QImage::Format_RGB888
                            ).rgbSwapped();
        ui->label_play->resize(QSize(capture.get(CV_CAP_PROP_FRAME_WIDTH),
                                     capture.get(CV_CAP_PROP_FRAME_HEIGHT)));
        ui->label_play->setScaledContents(true);
        QSize qs = ui->label_play->rect().size();
        ui->label_play->setPixmap(QPixmap::fromImage(img).scaled(qs));
        ui->label_play->setPixmap(QPixmap::fromImage(img));
    }
    int fresh_time = speed *total_frame_number /1000;
    int minute1 = fresh_time / 60;
    int second1 = (fresh_time - minute1 * 60) + 1;
    QString str_minute = QString("%1").arg(minute1);
    QString str_second = QString("%1").arg(second1);

    if(minute1 >=10 && second1 >= 10)
        str_time ="/" + str_minute + ":" + str_second;
    else if(second1 >= 10)
        str_time = "/0"+str_minute + ":" + str_second;
    else
        str_time = "/0"+str_minute + ":0" + str_second;
    ui->label_fresh_time->setText("00:00" + str_time);
    connect(&time_video, SIGNAL(timeout()), this, SLOT(playVideo()),
            Qt::UniqueConnection);
    connect(this,SIGNAL(currentValue(int)),this,SLOT(updateSliderValue(int)),
            Qt::UniqueConnection);
    menuInit();
    state = 0;
    minute = 0;
    second = 0;
}

void MainWindow::menuInit()
{
    rightbtn_menu.clear();
    play.setText(QString("播放"));
    rightbtn_menu.addAction(&play);
    edit.setText(QString("编辑"));
    rightbtn_menu.addAction(&edit);
    connect(&edit,SIGNAL(triggered(bool)),this,SLOT(editFrame()),
            Qt::UniqueConnection);
}

void MainWindow::showMenu()
{
    rightbtn_menu.exec(QCursor::pos());
}

void MainWindow::playVideo()
{
    capture >> frame;
    if(!frame.empty())
    {
        int now_frame = capture.get(CV_CAP_PROP_POS_FRAMES);

        //显示添加的字幕
        for(list<SubtitleInfo>::iterator iter = l_subtitle.begin();
            iter != l_subtitle.end();iter++)
        {
            if(now_frame >= iter->front_start && now_frame <= iter->front_end)
            {
                if(iter->front_Chinese_sign == 0)
                {
                    cv::putText(frame, iter->front_text,
                                Point(iter->front_x,
                                      iter->front_y),
                                FONT_HERSHEY_TRIPLEX, 0.8, Scalar(iter->front_color_b,
                                                                  iter->front_color_g,
                                                                  iter->front_color_r),
                                0.6, CV_AA);
                }
                if(iter->front_Chinese_sign == 1)
                {
                    QString str = QString::fromStdString(iter->front_text);
                    const wchar_t *theRealSub = reinterpret_cast<const wchar_t *>(str.utf16());
                    switch (iter->front_type) {
                    case 0:
                        cvtext = new CvxText("C:\\Windows\\Fonts\\AdobeSongStd-Light.otf"); //宋体
                        break;
                    case 1:
                        cvtext = new CvxText("C:\\Windows\\Fonts\\AdobeFangsongStd-Regular.otf"); //仿宋
                        break;
                    case 2:
                        cvtext = new CvxText("C:\\Windows\\Fonts\\AdobeKaitiStd-Regular.otf"); //楷体
                        break;
                    case 3:
                        cvtext = new CvxText("C:\\Windows\\Fonts\\msyh.ttc"); //微软雅黑
                        break;
                    case 4:
                        cvtext = new CvxText("C:\\Windows\\Fonts\\AdobeHeitiStd-Regular.otf"); //黑体
                        break;
                    default:
                        break;
                    }
                    Scalar size = iter->front_size;
                    cvtext->setFont(NULL,&size,NULL,NULL);
                    cvtext->putText(frame,theRealSub,Point(iter->front_x,
                                                           iter->front_y),
                                   Scalar(iter->front_color_b,iter->front_color_g,iter->front_color_r));

                    delete cvtext;
                    cvtext = NULL;
                }
            }
        }

        //显示添加的框选
        for(list<BoxInfo>::iterator iter1 = l_box.begin();
            iter1 != l_box.end();iter1++)
        {
            if(now_frame >= iter1->box_start && now_frame <= iter1->box_end)
            {
                switch (iter1->box_type) {
                //画矩形
                case 0:
                    rectangle(frame,Rect(iter1->box_x1,iter1->box_y1,
                                   (iter1->box_x2 - iter1->box_x1),
                                   (iter1->box_y2 - iter1->box_y1)),
                              Scalar(iter1->box_color_b,iter1->box_color_g,
                                     iter1->box_color_r),
                              iter1->box_line,
                              LINE_4);
                    break;
                //画椭圆
                case 1:
                    ellipse(frame,Point(iter1->box_x1 + (iter1->box_x2 -
                                                         iter1->box_x1) / 2,
                                  iter1->box_y1 + (iter1->box_y2 -
                                                   iter1->box_y1) / 2),
                            Size((iter1->box_x2 - iter1->box_x1) / 2,
                                 (iter1->box_y2 - iter1->box_y1) / 2),
                            0,
                            0,
                            360,
                            Scalar(iter1->box_color_b,iter1->box_color_g,
                                   iter1->box_color_r),
                            iter1->box_line,
                            LINE_4);
                    break;
                //画圆形
                case 2:
                    circle(frame,Point(iter1->box_x1 + (iter1->box_x2 -
                                                        iter1->box_x1) / 2,
                                iter1->box_y1 + (iter1->box_y2 -
                                                 iter1->box_y1) / 2),
                           sqrt((iter1->box_x2 - iter1->box_x1) *
                                (iter1->box_x2 - iter1->box_x1)
                                + (iter1->box_y2 - iter1->box_y1) *
                                (iter1->box_y2 - iter1->box_y1)) / 2,
                           Scalar(iter1->box_color_b,iter1->box_color_g,
                                  iter1->box_color_r),
                           iter1->box_line,
                           LINE_4);
                    break;
                //画直线
                case 3:
                    line(frame,
                         Point(iter1->box_x1,iter1->box_y1),
                         Point(iter1->box_x2,iter1->box_y2),
                         Scalar(iter1->box_color_b,iter1->box_color_g,
                                iter1->box_color_r),
                         iter1->box_line,
                         LINE_4);
                    break;
                default:
                    break;
                }
            }
        }


        QImage img = QImage((const unsigned char*)(frame.data),
                            frame.cols,
                            frame.rows,
                            QImage::Format_RGB888
                            ).rgbSwapped();
        ui->label_play->resize(QSize(capture.get(CV_CAP_PROP_FRAME_WIDTH),
                                     capture.get(CV_CAP_PROP_FRAME_HEIGHT)));
        ui->label_play->setScaledContents(true);
        QSize qs = ui->label_play->rect().size();
        ui->label_play->setPixmap(QPixmap::fromImage(img).scaled(qs));
        emit currentValue(now_frame/total_frame_number*1000.0);
        width = capture.get(CV_CAP_PROP_FRAME_WIDTH);
        height = capture.get(CV_CAP_PROP_FRAME_HEIGHT);
        if(second == 60 && minute < 60)
        {
            minute++;
            second = 0;
        }
        if(now_frame % rate == 0 && second < 60)
            second++;
    }
    else
    {
        QMessageBox::warning(NULL,"提示","视频播放结束!",QMessageBox::Ok);
        time_video.stop();
        ui->pushButton_replay->setEnabled(true);
        ui->pushButton_start->setEnabled(false);
        ui->pushButton_stop->setEnabled(false);
    }
}

void MainWindow::updateSliderValue(int value)
{
    ui->horizontalSlider_timeline->setValue(value);
    QString str_minute1 = QString("%1").arg(minute);
    QString str_second1 = QString("%1").arg(second);

    if(minute >=10 && second >= 10)
        ui->label_fresh_time->setText(str_minute1 + ":"
                                      + str_second1 + str_time);
    else if(second >= 10)
        ui->label_fresh_time->setText("0"+str_minute1 + ":"
                                      + str_second1 + str_time);
    else
        ui->label_fresh_time->setText("0"+str_minute1 + ":0"
                                      + str_second1 + str_time);
}

void MainWindow::editFrame()
{
    int frame_now = capture.get(CV_CAP_PROP_POS_FRAMES);
    if(state == 0)
    {
        state++;
        on_pushButton_stop_clicked();
        editform = new EditForm();
        connect(editform, SIGNAL(editClose(int)), this, SLOT(editClosed()));
        editform->getFrame(frame,width,height,frame_now);
        editform->show();
        editform->showFrame();
    }
    else
    {
        delete editform;
        editform = NULL;
        state --;
        on_pushButton_stop_clicked();
        editform = new EditForm();
        connect(editform, SIGNAL(editClose(int)), this, SLOT(editClosed()));
        editform->getFrame(frame,width,height,frame_now);
        editform->show();
        editform->showFrame();
    }
}

void MainWindow::editClosed()
{
    list<SubtitleInfo> l_subtitle1;
    list<BoxInfo> l_box1;
    l_subtitle1 = editform->getSubtitle();
    l_box1 = editform->getBox();
    list<SubtitleInfo>::iterator iter = l_subtitle.begin();
    list<BoxInfo>::iterator iter1 = l_box.begin();
    l_subtitle.splice(iter,l_subtitle1);
    l_box.splice(iter1,l_box1);

    qDebug()<<"run3";
}

void MainWindow::handleResults(int value)
{
    ui->progressBar_save_time->setValue(value);
    if(value == 100)
    {
        ui->label_save_message->setVisible(false);
        ui->progressBar_save_time->setVisible(false);
        QMessageBox::warning(NULL,"提示","新视频保存完成！",QMessageBox::Ok);
    }
}

void MainWindow::mousePressEvent(QMouseEvent *event)
{
    if(event->button() == Qt::RightButton)
    {
        showMenu();
    }
}

void MainWindow::closeEvent(QCloseEvent *event)
{
    event = event;
    qApp->exit();
}

void MainWindow::on_action_file_open_triggered()
{
    QString str = QFileDialog::getOpenFileName(this,"选择要播放的文件","/",
                                               "视频文件(*.avi);;");
    initVideo(str);
}

void MainWindow::on_action_file_save_triggered()
{
    QString file_full = QFileDialog::getSaveFileName(this,tr("保存视频文件"),"test",
                                                     tr("*.avi"));
    QFileInfo file = QFileInfo(file_full);
    QString file_name = file.fileName();
    QString file_path = file.absolutePath();
    QString save_path = file_path+"/"+file_name;
    path_save = save_path.toStdString();

    WriteVideo *writer = new WriteVideo();
    if(path_open != "")
    {
        ui->label_save_message->setVisible(true);
        ui->progressBar_save_time->setVisible(true);
        connect(writer,SIGNAL(resultReady(int)),this,SLOT(handleResults(int)));
        connect(writer,SIGNAL(finished()),writer,SLOT(deleteLater()));
        writer->setInfo(path_open, path_save, &l_subtitle, &l_box);
        writer->start();
    }
}

void MainWindow::on_action_exit_triggered()
{
    qApp->exit();
}

void MainWindow::on_pushButton_start_clicked()
{
    time_video.start(speed);
    ui->pushButton_start->setEnabled(false);
    ui->pushButton_stop->setEnabled(true);
    isplaying = true;
}

void MainWindow::on_pushButton_stop_clicked()
{
    time_video.stop();
    ui->pushButton_start->setEnabled(true);
    ui->pushButton_stop->setEnabled(false);
    isplaying = false;
}

void MainWindow::on_pushButton_replay_clicked()
{
    initVideo(QString::fromStdString(path_open));
    ui->pushButton_replay->setEnabled(false);
}

void MainWindow::on_horizontalSlider_timeline_valueChanged(int value)
{
    if(!isplaying)
    {
        double id = (value/1000.0)*total_frame_number;
        capture.set(CV_CAP_PROP_POS_FRAMES,id);
        playVideo();
    }
}
